package com.zisu.rabbitconsumer.component;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

/**
 * @Desc: "For Demo"
 * @Author: caixiang
 * @DATE: 2021/5/12 14:06
 */
//这是一条正常 的业务队列，当消息处理异常后 拒签消息 然后推送到 死信队列。（推送到死信后，虽然是拒签 但也会把这条消息从原业务队列中移除）
@Component
public class BusinessQueueWithDeadMessageReceive {

    //注意： 这种配置方式 只适用于 新建队列，如果 你要修改队列然后 修改以下配置 然后 重启 是不行的，要先在界面上 把原队列删除 在新建就ok了。
    //eq5_request_queue 这个队列 是 附加死信队列的，当有消息没有消费成功的时候 会自动丢到死信队列里面去
    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value="eq5_request_queue",durable = "true",
                            arguments = {
                                    //1. 死信队列Demo
                                    @Argument(name = "x-dead-letter-exchange", value = "es1_dead_message_exchange"),
                                    //可以为死信 指定routingKey，如果不指定routingKey的话 那么 会用原routingKey也就是 eq5_request
                                    @Argument(name = "x-dead-letter-routing-key", value = "es1_eq1_dead_message"),
                                    //这里设置的优先级 是这个队列承认的 最高优先级值，也就是说超过10 就 都一样。

                                    //2.优先级队列Demo
                                    @Argument(name = "x-max-priority", value = "10",type = "java.lang.Integer")
                                    //设置队列最大长度
                                    //@Argument(name = "x-max-length", value = "500", type = "java.lang.Integer")
                            }
                    ),
                    exchange = @Exchange(name = "es2_exchange",durable = "true",type = ExchangeTypes.DIRECT,ignoreDeclarationExceptions = "true"),
                    key = "eq5_request"
            )
    )
    @RabbitHandler
    public void es2ExchangeEq5(Message<?> message, Channel channel)throws Exception{
        System.out.println("==============DeadMessageReceive-es2-eq5_request_queue=================,priority:"+message.getHeaders().get("priority")+",attr1"+message.getHeaders().get("attr1"));
        Thread.sleep(100);

        Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);


        //模拟异常 ，然后 拒签消息 ，然后丢到死信队列
        try {
            System.err.println("处理消息的时候 出现异常，然后 拒签消息 ，然后丢到死信队列");
            throw new Exception("12333");
        }catch (Exception e){
            // 第一个false 是 不批量签收；第二个false 是 不重回队列
            channel.basicNack(deliveryTag,false,false);
        }

        //注意 这里特别注意 已经拒收的消息 再签收是要出错的，这里要特别注意。
        //channel.basicAck(deliveryTag,false);
        
    }
}
